home *** CD-ROM | disk | FTP | other *** search
/ Mac-Source 1994 July / Mac-Source_July_1994.iso / C and C++ / Commun⁄Network / Telnet 2.5.src.ThinkC / source / NCSA Driver / mactools.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-04-07  |  11.4 KB  |  449 lines  |  [TEXT/MPS ]

  1. /*
  2. *  mactools.c                by Gaige B. Paulsen
  3. *
  4. *  adapted from pctools.c      by Tim Krauskopf
  5. ****************************************************************************
  6. *                                                                          *
  7. *      part of:                                                            *
  8. *      TCP/UDP/ICMP/IP Network kernel for NCSA Telnet                      *
  9. *      by Tim Krauskopf                                                    *
  10. *                                                                          *
  11. *      National Center for Supercomputing Applications                     *
  12. *      152 Computing Applications Building                                 *
  13. *      605 E. Springfield Ave.                                             *
  14. *      Champaign, IL  61820                                                *
  15. *                                                                          *
  16. *                                                                          *
  17. ****************************************************************************
  18. *
  19. *  those generic tool-type things that only work on Macs.
  20. *  includes all hardware-level calls to Ethernet that are unique to the Mac
  21. *
  22. */
  23.  
  24. #include <stdio.h>
  25. #include <String.h>
  26.  
  27. #include <Dialogs.h>
  28. #include <Files.h>
  29. #include <AppleTalk.h>
  30. #include <Events.h>
  31. #include <Memory.h>
  32.  
  33. #include "protocol.h"
  34. #include "data.h"
  35. #include "fastnet.h"
  36. #include "configrec.h"
  37. #include "ethertalk.h"
  38. #include "atalk.h"                /* Dlayer to atalk conversion */
  39. #include "dlayer.h"
  40. #include "ip.h"
  41. #include "ether.h"
  42. #include "elistener.h"
  43. #include "listener.h"
  44. #include "maclook.h"
  45.  
  46. #ifdef MPW
  47. #define    movmem(y,x,z)    memcpy(x,y,z)
  48. #endif
  49.  
  50. extern short slip_connection;                    /* BYU 2.4.15 */
  51.  
  52. /*
  53.  * THE ALL-POWERFUL VARIABLE !!!!!!!!!!
  54.  */
  55.  
  56. int EtherNet
  57.   /*
  58.     specifies hardware interface to use.
  59.     Values are
  60.         -100    -- no hardware, serial port only                     BYU 2.4.15
  61.         -99        -- no hardware, using MacTCP (set up in userd.c)
  62.         -2        -- FastNet
  63.         -1        -- Kinetics Ether SC or Ether SE
  64.         0        -- LocalTalk ("built-in")
  65.         1        -- 3Com EtherLink/NB (or Apple EtherTalk)
  66.         9 .. 14 -- EtherLink/NB in specified NuBus slot
  67.   */
  68.     = 0;        /* default to LocalTalk */
  69.  
  70.  
  71.  
  72. /**********************************************************************/
  73. /*  netarpme
  74. *   send an arp to my address.  arpinterpret will notice any response.
  75. *   Checks for adapters which receive their own broadcast packets.
  76. */
  77. int netarpme
  78.   (
  79.     char *s
  80.   )
  81.   {
  82.     if (EtherNet) {    
  83.         reqarp((unsigned char *) s);    /* BYU LSC */
  84.     }
  85.     return(0);
  86.   }
  87.  
  88. /*
  89.  * ATdlayersend (ptr, size)
  90.  *  send size from ptr out the AT port
  91.  *    All outgoing conversions done here ! 
  92.  */
  93. ATdlayersend(ptr,size)            /*MAC: replaced */
  94. ARPKT *ptr;
  95. unsigned size;
  96. {
  97.     char *todata;
  98.     AddrBlock *destptr;
  99.     int ptype, tsize;
  100.     char wds[14], header[18];
  101.     MPPParamBlock pb;
  102.     static ATARPKT arpbuffer;
  103.  
  104.     int err;
  105.  
  106.     ptype = AIP;                                    /* Default to sending an IP Packet */
  107.  
  108.     pb.DDPsocket=IPSock;                            /* Sorry.... */
  109.     pb.DDPchecksumFlag=FALSE;                        /* who knows why, but we don't */
  110.     pb.DDPwdsPointer=wds;                            /* Here we go..... */
  111.     pb.MPPcsCode=246;                                /* We want to send a packet */
  112.  
  113.     todata=(char *)ptr + sizeof(DLAYER);            /* Point at the real data... */
  114.     destptr = (AddrBlock *) &ptr->d.dest[0];        /* BYU LSC - Where is the destination ? */
  115.     tsize = size- sizeof(DLAYER);                    /* Get transmission size */
  116.  
  117.     if (!memcmp( destptr, bseed, 6))                    /* Watch for Broadcasts */
  118.         memmove(destptr, ATbseed, 4);                /* BYU LSC */
  119.  
  120.     if (ptr->d.type == EARP) {
  121.         ptype=AARP;                                        /* Arp packet */
  122.         arpbuffer.hrd = 3;                                /* ATalk */
  123.         arpbuffer.hln = 4;
  124.         arpbuffer.pln = 4;
  125.         arpbuffer.pro = ptr->pro;
  126.         arpbuffer.op  = ptr->op;
  127.         memmove( &ptr->sha[0], &arpbuffer.sha[0], 4);    /* BYU LSC - Move addresses */
  128.         memmove( &ptr->spa[0], &arpbuffer.spa[0], 4);    /* BYU LSC */
  129.         memmove( &ptr->tha[0], &arpbuffer.tha[0], 4);    /* BYU LSC */
  130.         memmove( &ptr->tpa[0], &arpbuffer.tpa[0], 4);    /* BYU LSC */
  131.         todata= (char *) &arpbuffer;
  132.         todata+= sizeof(ATdlayer);                        /* New address to go from */
  133.         tsize = sizeof(ATARPKT)- sizeof(ATdlayer);
  134.         }
  135.         
  136.   /* note incorrect definition of BuildDDPwds in AppleTalk.h:
  137.     the destAddress arg is an AddrBlock, not a pointer to one! */
  138.     BuildDDPwds( wds, header, todata, *destptr, ptype, tsize );        /* BYU LSC - was "*(AddrBlock **) destptr" */
  139.     err=PWriteDDP( &pb, FALSE);
  140.     if (err!=0) putln("DDPW Error = %d");
  141. #ifdef SENDNOTICE    
  142.     else putln("send");
  143. #endif
  144.     return(err);
  145.     
  146. }
  147.  
  148. /*****************************************************************
  149.  *     E  T  H  E  R  N  E  T   /   E  T  H  E  R  T  A  L  K    *
  150.  *****************************************************************/
  151.  
  152. struct ETHERWDSstruct {
  153.     short len1;
  154.     DLAYER *ptr1;
  155.     short len2;
  156.     DLAYER *ptr2;
  157.     short term;
  158.     } EWDS;
  159.  
  160. int ETdlayersend            /*MAC: replaced */
  161.   (
  162.     DLAYER *ptr,
  163.     unsigned size
  164.   )
  165. {
  166.     EtParam ET;
  167.     int err;
  168.  
  169.     err = 0;
  170.     EWDS.len1=size;                    /* Could it would it in a WDS? */
  171.     EWDS.ptr1=ptr;
  172.     EWDS.len2=0;
  173.  
  174.     ET.address = &EWDS;
  175.  
  176.     /* err = */ ETcall( &ET, EWrite);
  177.     if (/* err != */ 0)
  178.         putln("ETW Error = %d");
  179. #ifdef SENDNOTICE    
  180.     else putln("send");
  181. #endif
  182.     return(err);
  183.     
  184. }
  185.  
  186. /**********************************************************************/
  187. /*   ETdemux    - Ethernet Version of DEMUX routine
  188. *
  189. *  returns the number of packets demuxed
  190. */
  191.  
  192. int ETdemux
  193.   (
  194.     int all
  195.   )
  196.     {
  197.     unsigned getcode;
  198.     int nmuxed,sizered;
  199.     typedef struct peek {
  200.         unsigned short count;
  201.         unsigned char dest[DADDLEN],
  202.             me[DADDLEN];
  203.         unsigned short type;
  204.     } Dpeek;
  205.  
  206.     Dpeek *firstlook;
  207.  
  208.     nmuxed = 0;
  209.  
  210.     do {                                    /* while all flag is on */
  211.  
  212.         if (bufinfo.bufbig > 0) { /*MAC*/
  213.  
  214.             nmuxed++;
  215.             firstlook = (Dpeek *)(bufinfo.bufread);     /*MAC where packet is */
  216.  
  217.             getcode = firstlook->type;            /* where does it belong? */
  218.  
  219.             switch (getcode) {                    /* what to do with it? */
  220.                 case EARP:
  221.                 case ERARP:
  222.                     arpinterpret((ARPKT *) firstlook->dest); /* handle [R]ARP packet */
  223.                     break;
  224.                 case EIP: 
  225.                     ipinterpret((IPKT *) firstlook->dest,NOT_FROM_SLIP);    /* BYU 2.4.15 - handle IP packet */
  226.                     break;
  227.                 default:
  228.                     break;
  229.             }
  230.  
  231.             sizered=(firstlook->count+sizeof(Dpeek));
  232.             bufinfo.bufbig-=sizered;
  233.             
  234. #ifdef DEBUGONLY
  235.             {
  236.             char s[60];
  237.             sprintf(s,"buf: %d, pkt: %d",bufinfo.bufbig,sizered);
  238.             putln(s);
  239.             }
  240. #endif
  241.             bufinfo.bufread+=(sizered+1) & 0xFFFE;
  242.  
  243.             if (bufinfo.bufbig<0) bufinfo.bufbig=0;
  244.             if (bufinfo.bufread>bufinfo.bufend) bufinfo.bufread=bufinfo.buforg;
  245.             
  246.         }
  247.         else {
  248.  
  249.             if (ETdeafreset()) {
  250.                 /* clear deaf flag, buffer overrun */
  251.                 putln("warning: buffer deaf, restarting");
  252.                 }
  253.  
  254.             all = 0;
  255.             }
  256.  
  257.  
  258.     } while (all);            /* should we look for more to deal with? */
  259.  
  260.  
  261.     return(nmuxed);          /* no packets anymore */
  262.  
  263. }
  264.  
  265. /************************************************************************/
  266. /*  dlayersend
  267. *
  268. *  usage:   err = dlayersend(ptr,size)
  269. *      err = 0 for successful, non-zero error code otherwise
  270. *      ptr is to a dlayer packet header
  271. *      size is the number of bytes total
  272. *
  273. *  This particular dlayer routine is for Ethernet.  It will have to be
  274. *  replaced for any other dlayer.
  275. *
  276. *  Assumes that dlayer-dependent initializations were made in protinit.c
  277. *  to help efficiency.
  278. *
  279. *  Ethernet addresses are resolved at higher levels because they will only
  280. *  need to be resolved once per logical connection, instead of once per
  281. *  packet.  Not too layer-like, but hopefully modular.
  282. *
  283. */
  284.  
  285. int dlayersend
  286.   (
  287.     DLAYER *ptr,
  288.     int size,                /* BYU 2.4.15 */
  289.     int connectionType        /* BYU 2.4.15 */
  290.   )
  291. {
  292.     if (connectionType > 0)                                /* BYU 2.4.15 */
  293.         SLIPdlayersend(ptr,size);                        /* BYU 2.4.15 */
  294.     else if (EtherNet== 0)                                /* BYU 2.4.15 */
  295.         return( ATdlayersend((ARPKT *) ptr,size));        /* BYU LSC */
  296.     else if (EtherNet==-2)                                /* BYU 2.4.15 - added "else" */
  297.         return( FNdlayersend(ptr,size));
  298.     else
  299.         return( ETdlayersend(ptr,size));
  300. }
  301.  
  302. int ATdemux
  303.   (
  304.     int all
  305.   )
  306. {
  307.     unsigned getcode;
  308.     int nmuxed,sizered, count;
  309.     ATARPKT *firstlook;
  310.     static ARPKT arpbuffer;
  311.     nmuxed = 0;
  312.  
  313.     do {                                    /* while all flag is on */
  314.  
  315.         if (bufinfo.bufbig > 0) {
  316.             nmuxed++;
  317.             firstlook = (ATARPKT *)(bufinfo.bufread);     /*MAC where packet is */
  318.  
  319.             getcode = firstlook->d.type;            /* where does it belong? */
  320.             count = firstlook->d.count;
  321.             memmove( firstlook->d.dest, arpbuffer.d.dest,4);        /* BYU LSC */
  322.             memmove( firstlook->d.me,   arpbuffer.d.me  ,4);        /* BYU LSC */
  323.             
  324.             switch (getcode) {                    /* what to do with it? */
  325.                 case AARP:
  326.                     arpbuffer.d.type=EARP;                            /* Arp packet */
  327.                     arpbuffer.hrd = 1;                                /* Enet */
  328.                     arpbuffer.hln = 6;
  329.                     arpbuffer.pln = 4;
  330.                     arpbuffer.pro = firstlook->pro;
  331.                     arpbuffer.op  = firstlook->op;
  332.                     memmove( &firstlook->sha[0], &arpbuffer.sha[0], 4);    /* BYU LSC - Move addresses */
  333.                     memmove( &firstlook->spa[0], &arpbuffer.spa[0], 4);    /* BYU LSC */
  334.                     memmove( &firstlook->tha[0], &arpbuffer.tha[0], 4);    /* BYU LSC */
  335.                     memmove( &firstlook->tpa[0], &arpbuffer.tpa[0], 4);    /* BYU LSC */
  336.                     arpinterpret(&arpbuffer);    /* handle ARP packet */
  337.                     break;
  338.                 case AIP:
  339.                     arpbuffer.d.type=EIP;
  340.                     memmove( &arpbuffer, firstlook, sizeof(DLAYER) );    /* BYU LSC */
  341.                     ipinterpret((IPKT *) firstlook,NOT_FROM_SLIP);        /* BYU 2.4.15 */
  342.                     break;
  343.                 default:
  344.                     break;
  345.             }
  346.  
  347.             sizered = count + sizeof(DLAYER);
  348.             bufinfo.bufbig-=sizered;
  349.             bufinfo.bufread+=(sizered+1) & 0xFFFE;
  350.  
  351.             if (bufinfo.bufbig<0) bufinfo.bufbig=0;
  352.             if (bufinfo.bufread>bufinfo.bufend) bufinfo.bufread=bufinfo.buforg;
  353.  
  354.         }
  355.         else 
  356.             all = 0;
  357.  
  358.  
  359.     } while (all);            /* should we look for more to deal with? */
  360.  
  361.  
  362.     return(nmuxed);          /* no packets anymore */
  363.  
  364. }
  365.  
  366. /**********************************************************************/
  367. /*   demux
  368. *      find the packets in the buffer, determine their lowest level
  369. *  packet type and call the correct interpretation routines
  370. *
  371. *  the 'all' parameter tells demux whether it should attempt to empty
  372. *  the input packet buffer or return after the first packet is dealt with.
  373. *
  374. *  returns the number of packets demuxed
  375. */
  376.  
  377. int demux
  378.   (
  379.     int all
  380.   )
  381. {
  382.     int total = 0;                        /* BYU 2.4.15 */
  383.     if (slip_connection)                /* BYU 2.4.15 */
  384.         total += SLIPdemux(all);        /* BYU 2.4.15 */
  385.     if (EtherNet==0)
  386.         total += ATdemux(all);            /* BYU 2.4.15 */
  387.     if (EtherNet==-2)
  388.         total += FNdemux(all);            /* BYU 2.4.15 */
  389.     else if (EtherNet > -99)             /* BYU 2.4.16 */
  390.         total += ETdemux(all);            /* BYU 2.4.15 */
  391.     return(total);                        /* BYU 2.4.15 */
  392. }
  393.  
  394. initbuffer()
  395.     {
  396.     raw=NewPtr(17000);                    /* BYU LSC - Added by GBP */
  397.     if (raw==NULL) return(-1);
  398.     bufinfo.bufpt = bufinfo.bufread = bufinfo.buforg
  399.                                          = raw;    /*  start at the beginning */
  400.  
  401.     bufinfo.bufend = raw+14500;            /* leave 2K breathing room, required */
  402.     bufinfo.buflim = 12000;             /* another 2K breathing room */
  403.     bufinfo.bufbig = 0;                    /* Added by GBP */
  404.  
  405.     if (EtherNet==0)
  406.         InitBufPtr(&bufinfo);
  407.     else if (EtherNet != -2) 
  408.         ETInitBufPtr( &bufinfo);
  409.     return(0);
  410. }
  411.  
  412. /***************************************************************************/
  413. /* dlayerinit
  414. *  Do machine dependent initializations of whatever hardware we have
  415. *  (happens to be 3com ethernet board here ) 
  416. */
  417. int dlayerinit
  418.   (
  419.     void
  420.   )
  421. {
  422.  
  423.     if (initbuffer())
  424.         return(-1);
  425.     if (EtherNet==0) 
  426.         return(atopen());
  427.     if (EtherNet==-2)
  428.         return(FNopen());
  429.     else if (EtherNet > -99)    /* BYU 2.4.15 */
  430.         return(ETopen());    /* Pass the Type along */
  431.     else if (EtherNet == -99)    /* BYU 2.4.15 MPW */
  432.         return(0);                /* BYU 2.4.15 MPW */
  433.     return(-1);                    /* BYU 2.4.15 MPW */
  434. }
  435.  
  436. int dlayershut
  437.   (
  438.     void
  439.   )
  440. {
  441.     if (EtherNet==0)
  442.         return(atclose());
  443.     if (EtherNet==-2)
  444.         return(FNclose());
  445.     else if (EtherNet > -100)    /* BYU 2.4.15 */
  446.         return(ETclose());
  447. }
  448.  
  449.